﻿using System;
using System.Collections.Generic;
using System.Text;

namespace daSyntaxAnalyser.SyntaxTree
{
    using daBase.Objects;

    /// <summary>
    /// Заголовок процедуры
    /// </summary>
    public class InnerProcedureHeadElement : IdElement, IMethodHeader
    {
        protected TokenInfo type;
        protected List<FunctionVarDeclarationElement> vars;
        protected List<DirectiveElement> directives;

        /// <summary>
        /// Тип процедуры (процедура, конструктор, деструктор)
        /// </summary>
        public TokenInfo Type { get { return type; } set { type = value; } }

        /// <summary>
        /// Список параметров процедуры
        /// </summary>
        public List<FunctionVarDeclarationElement> Vars { get { return vars; } set { vars = value; } }

        /// <summary>
        /// Список директив процедуры
        /// </summary>
        public List<DirectiveElement> Directives { get { return directives; } set { directives = value; } }

        /// <summary>
        /// Является ли метод внешним (директива external)
        /// </summary>
        public bool External
        {
            get
            {
                foreach (DirectiveElement directive in directives)
                    if (directive is ExternalDirectiveElement)
                        return true;
                return false;
            }
        }

        /// <summary>
        /// Будет ли метод определен позже (директива forward)
        /// </summary>
        public bool Forward
        {
            get
            {
                foreach (DirectiveElement directive in directives)
                    if (directive.Token.Token == DelphiTokens.Forward)
                        return true;
                return false;
            }
        }

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="Type">тип процедуры (процедура, конструктор, деструктор)</param>
        /// <param name="Name">имя процедуры</param>
        /// <param name="Vars">список параметров процедуры</param>
        /// <param name="Directives">список директив процедуры</param>
        /// <param name="Comments">комментарии, относящиеся к элементу</param>
        public InnerProcedureHeadElement(TokenInfo Type, TokenInfo Name, List<FunctionVarDeclarationElement> Vars, List<DirectiveElement> Directives, List<TokenInfo> Comments)
            : base(Name, Comments)
        {
            type = Type;
            vars = Vars;
            directives = Directives;
        }

        /// <summary>
        /// Представление элемента в строковом формате
        /// </summary>
        /// <returns>строковое представление элемента</returns>
        public override string ToString()
        {
            string result = string.Format("{0} {1}", type, id);
            if ((vars != null) && (vars.Count > 0))
                result += string.Format("({0})", vars.Join("; "));
            if ((directives != null) && (directives.Count > 0))
                result += string.Format("; {0}", directives.Join("; "));
            return string.Format("{0};", result);
        }

        /// <summary>
        /// Создание типизированного энумератора
        /// </summary>
        /// <returns>энумератор</returns>
        protected override IEnumerator<ISyntaxTreeElement> CreateEnumerator()
        {
            if (vars != null)
                foreach (FunctionVarDeclarationElement var in vars)
                    yield return var;
            if (directives != null)
                foreach (DirectiveElement directive in directives)
                    yield return directive;
        }
    }
}
